package ltd.nullpointer.tcp.core;

import com.boot2.core.utils.ByteUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import ltd.nullpointer.tcp.core.exception.MessageResolverException;
import ltd.nullpointer.tcp.core.message.AbstractTCPMessage;
import ltd.nullpointer.tcp.core.message.SysErrorMessage;
import ltd.nullpointer.tcp.core.resolver.MessageResolverFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.List;

/**
 * 
 * @ClassName: DeviceMessageDecoder
 * @Description: 解码器.
 * @author zhangweilin
 * @date 2017年11月9日 下午1:25:12
 *
 */

public class MessageDecoder extends ByteToMessageDecoder {
	public Log log = LogFactory.getLog(this.getClass());

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
		// 打印日志
//		ByteBuf copy = in.retainedDuplicate();
		int len = in.readableBytes();
		byte[] bytes = new byte[len];
		in.readBytes(bytes);
		in.resetReaderIndex();

//		String str = Hex.encodeHexString(bytes);
		String str = ByteUtils.hexBytes2HexString(bytes);
		bytes = null;
		log.info("收到完整hex报文 str: " + str);
		// 第一步为消息加密头，故不需要封装报文,则也不用返回到channel中
		AbstractTCPMessage abstractMessage=null;
		try {
			abstractMessage = MessageResolverFactory.getInstance().resolve(in);
			if (null!=abstractMessage) {
				out.add(abstractMessage);
			}
		} catch (MessageResolverException e) {
			e.printStackTrace();
			SysErrorMessage errorMessage = new SysErrorMessage(e.getErrCode(),e.getMessage());
			out.add(errorMessage);
		}
		in.skipBytes(in.readableBytes());
		 
		// 防止抛DeviceMessageDecoder.decode() did not read anything but decoded a message.
		log.debug("MessageDecoder.decode2: " + abstractMessage);
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		log.error("Decoder error: " + cause.getMessage(), cause);
		cause.printStackTrace();
		ctx.close();
	}

}
